<<<<<<< .mine
﻿package su.fishr.effects.flySquares 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import su.fishr.display.SmoothResizeDObject;
	import com.greensock.*;
	import com.greensock.easing.*;
	import com.greensock.TimelineLite;
	
	/**
	 *  Основной класс вывода анимации.
	 * - по сигналу модели выводит очередной
	 *   фрагмент на сцену,
	 * - используя TweenMax - анимацию двигает 
	 *   фрагмент к месту конечного позиционирования,
	 * - по окончании анимации уничтожает фрагменты
	 *   подменяя конечным изображением.
	 * 
	 * @author fish_r
	 */
	internal class VFlySquares extends Sprite 
	{
		public const END_BOMB:String = "endBomb";
	
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*						V A R I A B L E ' S  	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
		protected var _cFlySquares:CFlySquares;
		protected var _mFlySquares:MFlySquares;
		protected var _newFragment:Bitmap;
		protected var _rate:Number
		protected var _easing:Function;
		///перем. отвечает за отключение
		///прозрачных фрагментов из твина
		///в значении true фрагменты 1-ый
		///пикс. которых имеет цвет 0
		///будут сразу занимать свои места без
		///твин-перемещения.
		private var _blackOff:Boolean;
		private var _arrFilters:Array;
		///@private///
		private var _tweenLine:TimelineLite;
		///для хранения фильтров и значения вероятности 
		///их применения.
		private var _stepsFilters:Array;
		private var _lastme:Bitmap;
		private var _countAdd:int;
		private var _finalRender:Bitmap;
		private var _propBomb:Array;
		///@private///
		private var _timeLineLite:TimelineLite;

	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*						P R O P E R T I E S  	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
		
		public function set cFlySquares(value:CFlySquares):void 
		{
			_cFlySquares = value;
		}
		
		public function get rate():Number 
		{
			return Math.random() * _rate + .1 ;
		}
		
		public function set rate(value:Number):void 
		{
			_rate = value;
		}
		
		public function set blackOff(value:Boolean):void 
		{
			_blackOff = value;
		}
		
		public function set stepsFilters(value:Array):void 
		{
			_stepsFilters = value;
		}
		
		public function set propBomb(value:Array):void 
		{
			_propBomb = value;
		}
	
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*	 				C O N S T R U C T O R
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/	
		
		
		
		public function VFlySquares(obj:MFlySquares) 
		{
			_mFlySquares = obj;
			super();
			
			if (parent) init(null);
			else this.addEventListener(Event.ADDED, init);
			
		}
		
	
	/**-------------------------------------------------------------------------------
	* 
	*	   						P U B L I C 
	*
	* --------------------------------------------------------------------------------
	*/
	//{
	
		/**
		 *  При включенном effectBomb  получает ссылку 
		 * на массив всех фрагментов объекта.
		 * @param	e
		 */
		private function mFlySquaresONListen(e:Event):void 
		{
			_mFlySquares.removeEventListener(_mFlySquares.ADD_FRAGMENT, mFlySquaresONListen);
			///двух уровневый массив:
			/// - первый уровень - столбцы,
			/// - второй - строки.
			var allFragments:Array = _mFlySquares.arrFragments.slice(0, _mFlySquares.arrFragments.length)
			var duration:Number = _propBomb[1] > 0?_propBomb[1]:_rate;
			
			var fragment:Bitmap;
			_timeLineLite = new TimelineLite( { delay: _propBomb[0], paused: false, align: TweenAlign.START, onComplete: endOffBombListener } );
			///@private///
			var tweenMax:TweenMax;
			
			for (var i:uint = 0; i < allFragments.length; i++)
			{
				for ( var j:uint = 0; j < allFragments[i].length; j++)
				{
					/**
					 * Получаемый последний член имеет вид:
					 * allFragments[i][j] : (x=115, y=1), - начальные координаты
					 *  				  0,20, - конечные координаты
					 * 					  [object Bitmap] - фрагмент
					 */
					fragment = allFragments[i][j][3];
					fragment.x =  allFragments[i][j][1];
					fragment.y = allFragments[i][j][2];
					this.addChild( fragment );
					var param:Object = { x:allFragments[i][j][0].x, 
												y:allFragments[i][j][0].y,
													ease:_propBomb[2]};
					if ( _stepsFilters && Math.random() >= ( 1 - _stepsFilters[0] ) )
					{
						if ( _stepsFilters[1] )param = createFilter( param, _stepsFilters[1]);
					}
					
					tweenMax = new TweenMax( fragment, duration, param)
											
					_timeLineLite.append( tweenMax, - duration );
				}
			}
			_mFlySquares.addEventListener(_mFlySquares.ADD_FRAGMENT, addFragmentListener);
	
		}
		
		
	//}
	
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*						P R O T E C T E D 	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
	
	
		
		
		protected function init(e:Event):void 
		{
			if ( e.target is VFlySquares === false ) return;
			removeEventListener(Event.ADDED, init);
			_arrFilters = new Array();
			if ( _propBomb )_mFlySquares.addEventListener( _mFlySquares.SELECT_SIZE, mFlySquaresONListen);
			else _mFlySquares.addEventListener(_mFlySquares.ADD_FRAGMENT, addFragmentListener);
			
			this.addEventListener(Event.REMOVED_FROM_STAGE, disposeAllBitmap);
		}
		


		protected function endTweenListener(obj:Bitmap):void 
		{
			TweenMax.killTweensOf(obj);

			if ( obj === _lastme ) endArrayFragment();
			
			
			if (! _stepsFilters || !_stepsFilters[3]) return;
			
			if (Math.random() >= ( 1 - _stepsFilters[0] ) )
			{
				TweenMax.to( obj, 0, _stepsFilters[3] );
				_arrFilters.push(obj);
			}
		}
		
		
		protected function endWorkListener(e:Event = null):void 
		{
			this.removeEventListener(Event.REMOVED_FROM_STAGE, disposeAllBitmap);
			
			TweenMax.killAll(true, true);
			
			/*
			 * Формирование финальной битмапы делается: 
			 * - если ранее не формировалась,
			 * - если фрагментов в модели уже нет 
			 * 	 (т.е. определяем: закончено ли складывание).
			*/
			if ( !_finalRender && this.numChildren > 0)
			{
				_finalRender = SmoothResizeDObject.resizeDisplayObject( this, "height", this.height, false );
				this.addChild( _finalRender );
			}
			disposeAllBitmap();
			
			
			
		}
		
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*							P R I V A T E 	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
		private function addFragmentListener(e:Event):void 
		{
			
			var item:Array = _mFlySquares.addFragment;
						
			_easing = SelectEaseing();
			_newFragment = item[3];
			
			TweenMax.killTweensOf(_newFragment);
			///если полученый фрагмент прозрачен сразу
			///выкладываем его на позицию.
			if (_blackOff === true && _newFragment.bitmapData.getPixel(0, 0) === 0 )
			{
				_newFragment.x = item[1];
				_newFragment.y = item[2];
				return;
			}

			this.addChild(_newFragment);
			
			tweenStart(item);
			
			
			
			
		}
		

		
		/**
		 *  Все фрагменты заняли свои места.
		 * Если нет необходимости применять фильтры - заканчиваем работу,
		 * иначе - добавляем фильтры.
		 */	
		private function endArrayFragment():void 
		{
			if (!_arrFilters.length  || !_stepsFilters[4])endWorkListener();
			else
			{	
				_tweenLine = new TimelineLite({onComplete: endWorkListener});
				_tweenLine.insertMultiple( TweenMax.allTo(_arrFilters, _rate, _stepsFilters[4] ),  _tweenLine.duration );
			}
			
			
		}
		
		private function tweenStart(item:Array):void
		{
			_countAdd++;
			
			
			var options:Object = { x:item[1], y:item[2], ease:_easing, onComplete: endTweenListener, onCompleteParams:[item[3]] };

			if ( _stepsFilters && Math.random() >= ( 1 - _stepsFilters[0] ) )
			{
				options = createFilter(options, _stepsFilters[2] );
				_arrFilters.push(item[3]);
			}
			
			if ( _countAdd === _mFlySquares.countFr )
			{
				_lastme = item[3];
				TweenMax.to(item[3], _rate + .2,  options);
				
			}
			else
			{
				TweenMax.to(item[3], this.rate,  options);
			}
			
			
		}
		



		
		private function disposeAllBitmap(e:Event = null):void
		{
			_cFlySquares.endPlayDispatch();
			_mFlySquares.removeEventListener( _mFlySquares.SELECT_SIZE, mFlySquaresONListen);
			_mFlySquares.removeEventListener(_mFlySquares.ADD_FRAGMENT, addFragmentListener);
			this.addEventListener(Event.ENTER_FRAME, disposePortion);
		}
		
		private function disposePortion(e:Event):void
		{
			
			
			if (this.numChildren === 0 ) 
			{
				this.removeEventListener(Event.ENTER_FRAME, disposePortion);
				return;
				
			}
			
			var bitmap:Bitmap;
			var bitmapData:BitmapData;
			
			
			for (var i:uint = 100; i > 0 ; i-- )
			{
				if ( this.numChildren === 1 )
				{
					
					
					this.removeEventListener(Event.ENTER_FRAME, disposePortion);
					
					if ( this.stage === null )
					{
						this.removeChildAt(0);
						/**
						 * если прогресс не успел дойти до 100-а, а объект
						 * был удален то скрина объекта может на сцене и
						 * не быть.
						 */
						if ( _finalRender )
						{
							_finalRender.bitmapData.dispose();
							_finalRender.bitmapData = null;
							_finalRender = null;

							_newFragment = null;
						}
						

						
						
					}
					else this.addEventListener(Event.REMOVED_FROM_STAGE, disposeAllBitmap);
					
					
					
					break;
				}

				bitmap = Bitmap( this.getChildAt(0));
				bitmap.filters = null;
				bitmapData = bitmap.bitmapData;
				this.removeChild(bitmap);
				if ( bitmapData )bitmapData.dispose();
				bitmap = null;
				bitmapData = null;
				
				
				
			}

			
		}
		
		
				private function SelectEaseing():Function
		{
			var easin:Array = new Array (  
											Sine.easeIn,
											Quint.easeIn,
											Quart.easeIn,
			                                Quad.easeIn,
											Expo.easeIn,
											Elastic.easeIn,
											Back.easeIn,
											Bounce.easeIn,
											Circ.easeIn,
											Cubic.easeIn,
											Sine.easeOut,
											Quint.easeOut,
											Quart.easeOut,
			                                Quad.easeOut,
											Expo.easeOut,
											Elastic.easeOut,
											Back.easeOut,
											Bounce.easeOut,
											Circ.easeOut,
											Cubic.easeOut
										);
			
			var randSelect:uint = Math.random() * easin.length;
			return easin[randSelect];
		}
		
		/**
		 *  Добавляет фильтры плагины к прочим пер. 
		 * вызываемого твина.
		 * @param	obj
		 * @param	filter
		 * @return  исходный хеш с добавленными фильтрами для TweenMax-а
		 */
		private function createFilter(obj:Object, filter:Object):Object
		{

			for (var name:Object in filter )
			{
				obj[name] = filter[name];

			}
			
			return obj;
			
			
		}
		
		private function endOffBombListener():void 
		{
			this.dispatchEvent( new Event( END_BOMB ));
		}
		
		
		
	}
	

	
	

}=======
﻿package su.fishr.effects.flySquares 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import su.fishr.display.SmoothResizeDObject;
	///@private///
	import com.greensock.*;
	///@private///
	import com.greensock.easing.*;
	///@private///
	import com.greensock.TimelineLite;
	
	/**
	 *  Основной класс вывода анимации.
	 * - по сигналу модели выводит очередной
	 *   фрагмент на сцену,
	 * - используя TweenMax - анимацию двигает 
	 *   фрагмент к месту конечного позиционирования,
	 * - по окончании анимации уничтожает фрагменты
	 *   подменяя конечным изображением.
	 * 
	 * @author fish_r
	 */
	internal class VFlySquares extends Sprite 
	{
		public const END_BOMB:String = "endBomb";
	
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*						V A R I A B L E ' S  	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
		protected var _cFlySquares:CFlySquares;
		protected var _mFlySquares:MFlySquares;
		protected var _newFragment:Bitmap;
		protected var _rate:Number
		protected var _easing:Function;
		///перем. отвечает за отключение
		///прозрачных фрагментов из твина
		///в значении true фрагменты 1-ый
		///пикс. которых имеет цвет 0
		///будут сразу занимать свои места без
		///твин-перемещения.
		private var _blackOff:Boolean;
		private var _arrFilters:Array;
		///@private///
		private var _tweenLine:TimelineLite;
		private var _lastme:Bitmap;
		private var _countAdd:int;
		private var _finalRender:Bitmap;
		private var _propBomb:Array;
		///@private///
		private var _timeLineLite:TimelineLite;

	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*						P R O P E R T I E S  	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
		
		public function set cFlySquares(value:CFlySquares):void 
		{
			_cFlySquares = value;
		}
		
		public function get rate():Number 
		{
			return Math.random() * _rate + .1 ;
		}
		
		public function set rate(value:Number):void 
		{
			_rate = value;
		}
		
		public function set blackOff(value:Boolean):void 
		{
			_blackOff = value;
		}
		
		public function set propBomb(value:Array):void 
		{
			_propBomb = value;
		}
		
		///информирует подкласс о режиме "effect bomb"
		public function get propBomb():Array
		{
			return _propBomb;
		}
	
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*	 				C O N S T R U C T O R
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/	
		
		
		
		public function VFlySquares(obj:MFlySquares) 
		{
			_mFlySquares = obj;
			super();
			
			if (parent) init(null);
			else this.addEventListener(Event.ADDED, init);
			
		}
		
	
	/**-------------------------------------------------------------------------------
	* 
	*	   						P U B L I C 
	*
	* --------------------------------------------------------------------------------
	*/
	//{
	
		
		
		
	//}
	
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*						P R O T E C T E D 	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
	
	
		
		
		protected function init(e:Event):void 
		{
			if ( e.target is VFlySquares === false ) return;
			removeEventListener(Event.ADDED, init);
			if ( _propBomb )_mFlySquares.addEventListener( _mFlySquares.SELECT_SIZE, mFlySquaresONListen);
			else _mFlySquares.addEventListener(_mFlySquares.ADD_FRAGMENT, addFragmentListener);
			
			this.addEventListener(Event.REMOVED_FROM_STAGE, disposeAllBitmap);
		}
		


		protected function endTweenListener(obj:Bitmap):void 
		{
			TweenMax.killTweensOf(obj);

			if ( obj === _lastme ) endWorkListener();
		}
		
		
		protected function endWorkListener(e:Event = null):void 
		{
			this.removeEventListener(Event.REMOVED_FROM_STAGE, disposeAllBitmap);
			
			TweenMax.killAll(true, true);
			
			/*
			 * Формирование финальной битмапы делается: 
			 * - если ранее не формировалась,
			 * - если фрагментов в модели уже нет 
			 * 	 (т.е. определяем: закончено ли складывание).
			*/
			if ( !_finalRender && this.numChildren > 0)
			{
				_finalRender = SmoothResizeDObject.resizeDisplayObject( this, "height", this.height, false );
				this.addChild( _finalRender );
			}
			disposeAllBitmap();
			
			
			
		}
		
		/**
		 * костыль, переопределяется в подклассе.
		 * Мне стыдно, но виноваты GreenSock, так
		 * как не пользуют события.
		 *  Перехватывает момент старта, для подкласса.
		 * Чтобы успеть наложить маску на объект _background
		 */
		protected function initTweenBombListener():void {}
		
		
		protected function addFragmentListener(e:Event):void 
		{
			
			var item:Array = _mFlySquares.addFragment;
						
			_easing = SelectEaseing();
			_newFragment = item[3];
			
			TweenMax.killTweensOf(_newFragment);
			///если полученый фрагмент прозрачен сразу
			///выкладываем его на позицию.
			if (_blackOff === true && _newFragment.bitmapData.getPixel(0, 0) === 0 )
			{
				_newFragment.x = item[1];
				_newFragment.y = item[2];
				return;
			}

			this.addChild(_newFragment);
			
			tweenStart(item);
			
			
			
			
		}
		
	/**-------------------------------------------------------------------------------
	* 
	* 	
	* 
	*							P R I V A T E 	
	*
	* 
	* 
	* --------------------------------------------------------------------------------
	*/
	
	
		/**
		 *  При включенном effectBomb  получает ссылку 
		 * на массив всех фрагментов объекта.
		 * @param	e
		 */
		private function mFlySquaresONListen(e:Event):void 
		{
			_mFlySquares.removeEventListener(_mFlySquares.ADD_FRAGMENT, mFlySquaresONListen);
			///двух уровневый массив:
			/// - первый уровень - столбцы,
			/// - второй - строки.
			var allFragments:Array = _mFlySquares.arrFragments.slice(0, _mFlySquares.arrFragments.length)
			var duration:Number = _propBomb[1] > 0?_propBomb[1]:_rate;
			
			var fragment:Bitmap;
			_timeLineLite = new TimelineLite( { delay: _propBomb[0], paused: false, align: TweenAlign.START, onComplete: endOffBombListener } );
			///@private///
			var tweenMax:TweenMax;
			
			for (var i:uint = 0; i < allFragments.length; i++)
			{
				for ( var j:uint = 0; j < allFragments[i].length; j++)
				{
					/**
					 * Получаемый последний член имеет вид:
					 * allFragments[i][j] : (x=115, y=1), - начальные координаты
					 *  				  0,20, - конечные координаты
					 * 					  [object Bitmap] - фрагмент
					 */
					fragment = allFragments[i][j][3];
					fragment.x =  allFragments[i][j][1];
					fragment.y = allFragments[i][j][2];
					this.addChild( fragment );
					var param:Object = { x:allFragments[i][j][0].x, 
												y:allFragments[i][j][0].y,
												 onInit : initTweenBombListener,
													ease:_propBomb[2] };
													
					tweenMax = new TweenMax( fragment, duration, param)
											
					_timeLineLite.append( tweenMax, - duration );
				}
			}
			_mFlySquares.addEventListener(_mFlySquares.ADD_FRAGMENT, addFragmentListener);
	
		}
		

		private function tweenStart(item:Array):void
		{
			_countAdd++;
			
			
			var options:Object = { x:item[1], y:item[2], ease:_easing, onComplete: endTweenListener, onCompleteParams:[item[3]] };
			
			if ( _countAdd === _mFlySquares.countFr )
			{
				_lastme = item[3];
				TweenMax.to(item[3], _rate + .2,  options);
				
			}
			else
			{
				TweenMax.to(item[3], this.rate,  options);
			}
			
			
		}
		



		
		private function disposeAllBitmap(e:Event = null):void
		{
			_cFlySquares.endPlayDispatch();
			_mFlySquares.removeEventListener( _mFlySquares.SELECT_SIZE, mFlySquaresONListen);
			_mFlySquares.removeEventListener(_mFlySquares.ADD_FRAGMENT, addFragmentListener);
			this.addEventListener(Event.ENTER_FRAME, disposePortion);
		}
		
		private function disposePortion(e:Event):void
		{
			
			
			if (this.numChildren === 0 ) 
			{
				this.removeEventListener(Event.ENTER_FRAME, disposePortion);
				return;
				
			}
			
			var bitmap:Bitmap;
			var bitmapData:BitmapData;
			
			
			for (var i:uint = 100; i > 0 ; i-- )
			{
				if ( this.numChildren === 1 )
				{
					
					
					this.removeEventListener(Event.ENTER_FRAME, disposePortion);
					
					if ( this.stage === null )
					{
						this.removeChildAt(0);
						/**
						 * если прогресс не успел дойти до 100-а, а объект
						 * был удален то скрина объекта может на сцене и
						 * не быть.
						 */
						if ( _finalRender )
						{
							_finalRender.bitmapData.dispose();
							_finalRender.bitmapData = null;
							_finalRender = null;

							_newFragment = null;
						}
						

						
						
					}
					else this.addEventListener(Event.REMOVED_FROM_STAGE, disposeAllBitmap);
					
					
					
					break;
				}

				bitmap = Bitmap( this.getChildAt(0));
				bitmap.filters = null;
				bitmapData = bitmap.bitmapData;
				this.removeChild(bitmap);
				if ( bitmapData )bitmapData.dispose();
				bitmap = null;
				bitmapData = null;
				
				
				
			}

			
		}
		
		
				private function SelectEaseing():Function
		{
			var easin:Array = new Array (  
											Sine.easeIn,
											Quint.easeIn,
											Quart.easeIn,
			                                Quad.easeIn,
											Expo.easeIn,
											Elastic.easeIn,
											Back.easeIn,
											Bounce.easeIn,
											Circ.easeIn,
											Cubic.easeIn,
											Sine.easeOut,
											Quint.easeOut,
											Quart.easeOut,
			                                Quad.easeOut,
											Expo.easeOut,
											Elastic.easeOut,
											Back.easeOut,
											Bounce.easeOut,
											Circ.easeOut,
											Cubic.easeOut
										);
			
			var randSelect:uint = Math.random() * easin.length;
			return easin[randSelect];
		}
		
		
		private function endOffBombListener():void 
		{
			this.dispatchEvent( new Event( END_BOMB ));
		}
		
		
		
	}
	

	
	

}>>>>>>> .r1349
